#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512  // 缓冲区大小

int main() 
{
    /* 初始化 Winsock */
    WSADATA wsaData;
    int iResult;

    // 调用 WSAStartup 函数以启用 WS2_32.dll 库
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if(iResult != 0)
    {
        std::cout << "WSAStartup failed: " << iResult << std::endl;
        return 1;
    }

    /* 创建套接字 */
    SOCKET clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(clientSocket == INVALID_SOCKET)
    {
        std::cout << "create socket failed with error: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    /* 发送数据 */
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET; // IPv4 地址族
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 监听所有可用的 IP 地址 or INADDR_ANY
    serverAddr.sin_port = htons(27015); // 监听的端口号

    const char* message = "Hello, server! from UDP"; // 要发送的消息
    iResult = sendto(clientSocket, message, strlen(message), 0, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if(iResult > 0)
    {
        std::cout << "bytes send to: " << iResult << std::endl;
    }
    else
    {
        std::cout << "sendto failed with error: " << WSAGetLastError() << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    /* 接收数据 */
    int serverAddrLen = sizeof(serverAddr);
    char recvbuf[1024];
    iResult = recvfrom(clientSocket, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&serverAddr, &serverAddrLen);
    if(iResult > 0)
    {
        std::cout << "bytes received: " << iResult << std::endl;
        std::cout << "received message: " << recvbuf << std::endl;
    }
    else
    {
        std::cout << "recvfrom failed with error: " << WSAGetLastError() << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }



    /* 关闭套接字 */
    closesocket(clientSocket);
    // 清理
    WSACleanup();

    std::cout << "server: bye"<< std::endl;
    return 0;
}